<?php

namespace App\Service\OpenShop\SiteLocation;

use App\Enums\OpenShop\FeishuMini\ProgrammingEnum;
use App\Enums\OpenShop\InvestmentPromotion\SiteLocationEnum;
use App\Models\Common\MapNationalStreetModel;
use App\Models\Common\ResourcesModel;
use App\Models\OpenShop\Common\SiteLocationMallModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Service\BaseService;
use Ballen\Distical\Calculator as DistanceCalculator;
use Ballen\Distical\Entities\LatLong;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Redis;
use League\Geotools\Coordinate\Coordinate;
use League\Geotools\Polygon\Polygon;

class SiteLocationMallService extends BaseService
{

    /**
     * 根据城市名称和商城名称模糊匹配
     * @param $cityCode
     * @param $mallName
     * @param $lat
     * @param $lng
     * @return array
     * @throws GuzzleException
     */
    public static function getNearbyMall($cityCode, $mallName, $lat, $lng): array
    {

        $siteLocationMallIdArr = [];
        $dotList = Redis::georadius('tiger:wanggui:dot', $lng, $lat, '10000', 'm', ['WITHDIST', 'ASC']);
        foreach ($dotList as $dot) {
            if (mb_strpos($dot[0], 'SC11') === 0) {
                $siteLocationMallIdArr[$dot[0]] = $dot[1];
            }
        }

        $siteLocationModel = SiteLocationMallModel::query()
            ->where('cityCode', $cityCode)
            ->when(mb_strlen($mallName), function ($query) use ($mallName){
                $query->where('mallName', 'like', "%{$mallName}%");
            })
            ->whereIn('wgNumber', array_keys($siteLocationMallIdArr))
            ->get();

        $mallIds = $siteLocationModel->pluck('mallId')->toArray() ?? [];

        //获得观远的数据
        try {
            $guanyuanData = count($mallIds) ? array_column(GuanyuanDataService::getMallDataByCity($mallIds), null, '商场ID') : [];
        } catch (\Exception $exception) {
            $guanyuanData = [];
        }

        return $siteLocationModel->map(function (SiteLocationMallModel $locationMallModel) use ($guanyuanData, $lat, $lng, $siteLocationMallIdArr) {
            $mallLat = (float)(isset($guanyuanData[$locationMallModel->mallId]) ? $guanyuanData[$locationMallModel->mallId]['mall_y'] : $locationMallModel->lat);
            $mallLng = (float)(isset($guanyuanData[$locationMallModel->mallId]) ? $guanyuanData[$locationMallModel->mallId]['mall_x'] : $locationMallModel->lng);
            return [
                'id'          => $locationMallModel->id,
                'type'        => ProgrammingEnum::PROGRAMMING_MALL,
                'mallId'      => $locationMallModel->mallId,
                'mallName'    => $locationMallModel->mallName,
                'isWhiteList' => isset($guanyuanData[$locationMallModel->mallId]),
                'mallGrade'   => (isset($guanyuanData[$locationMallModel->mallId]) ? $guanyuanData[$locationMallModel->mallId]['商场分级'] : (SiteLocationMallModel::SITE_MALL_GRADE_MAPPING[$locationMallModel->grade] ?? '')),
                'mallStatus'  => isset($guanyuanData[$locationMallModel->mallId]),
                'province'    => (isset($guanyuanData[$locationMallModel->mallId]) ? $guanyuanData[$locationMallModel->mallId]['省份'] : $locationMallModel->province),
                'city'        => (isset($guanyuanData[$locationMallModel->mallId]) ? $guanyuanData[$locationMallModel->mallId]['城市'] : $locationMallModel->city),
                'district'    => (isset($guanyuanData[$locationMallModel->mallId]) ? $guanyuanData[$locationMallModel->mallId]['区县'] : $locationMallModel->district),
                'address'     => (isset($guanyuanData[$locationMallModel->mallId]) ? $guanyuanData[$locationMallModel->mallId]['地址'] : $locationMallModel->address),
                'lng'         => $mallLng,
                'lat'         => $mallLat,
                'distance'    => round($siteLocationMallIdArr[$locationMallModel->wgNumber] / 1000, 5),
            ];
        })->filter()->sortBy('distance')->values()->toArray();
    }


    /**
     * 根据经纬度获得附近的街道
     * @param $cityCode
     * @param $streetName
     * @param $lat
     * @param $lng
     * @param int $distance
     * @return array
     */
    public static function getNearbyStreet($cityCode, $streetName, $lat, $lng, int $distance = 500): array
    {
        $streetWgNumberArr = [];
        $dotList           = Redis::georadius('tiger:wanggui:dot', $lng, $lat, $distance, 'm', ['WITHDIST', 'ASC']);
        foreach ($dotList as $dot) {
            if (mb_strpos($dot[0], 'JD55') === 0) {
                $streetWgNumberArr[$dot[0]] = (int)$dot[1];
            }
        }

        $data = [];
        MapNationalStreetModel::query()
            ->whereIn('wgNumber', array_keys($streetWgNumberArr))
            ->when($cityCode, function ($query) use ($cityCode) {
                $query->where('cityCode', $cityCode);
            })
            ->when(mb_strlen($streetName), function ($query) use ($streetName) {
                $query->where('address', 'like', "%{$streetName}%");
            })
            ->chunkById(100, function ($streets) use ($lat, $lng, &$data, $streetWgNumberArr) {
                foreach ($streets as $street) {
                    $coords    = json_decode($street->coords, true);
                    $polygon   = new Polygon($coords); // 经度在前纬度在后
                    $inPolygon = $polygon->pointInPolygon(new Coordinate([$lng, $lat]));
                    $onPolygon = $polygon->pointOnBoundary(new Coordinate([$lng, $lat]));
                    $data[]    = [
                        'id'       => $street->id,
                        'type'     => ProgrammingEnum::PROGRAMMING_STREET,
                        'grade'    => $street->grade,
                        'gradeStr' => ProgrammingEnum::GRADE_MAPPING[$street->grade] ?? '',
                        'meet'     => $inPolygon || $onPolygon,
                        'wgNumber' => $street->wgNumber,
                        'lng'      => $street->lng,
                        'lat'      => $street->lat,
                        'boundary' => $coords,
                        'distance' => $streetWgNumberArr[$street->wgNumber] ?? '-',
                        //'name'     => ($tempName = (explode($street->name, $street->address)[1] ?? $street->name)) == $street->name ?: $street->name . $tempName,
                        'name'     => $street->name,
                        'address'  => ($tempName = (explode($street->name, $street->address)[1] ?? $street->name)) == $street->name ?: $street->name . $tempName
                    ];
                }
            });
        return collect($data)->sortBy('distance')->values()->toArray();
    }


    //获得表单
    public static function createdMallJudge(OpenShopSiteLocationModel $openShopSiteLocationModel): array
    {
        $isMall = true;
        $isHave = false;

        //手填的需要特殊处理  判断手填的依据判断mallId是否为MALL-
        if (strpos($openShopSiteLocationModel->mallId, 'MALL-') !== false) {
            $isMall = false;
        }

        //获得图片
        $starImg    = [];
        $shopNumImg = [];
        ResourcesModel::query()
            ->where('module', ResourcesModel::MODULE_TYPE_SITE_MALL)
            ->where('business', ResourcesModel::BUSINESS_SITE_LOCATION_MALL)
            ->where('businessId', 0)
            ->get()
            ->each(function (ResourcesModel $resourcesModel) use ($openShopSiteLocationModel, &$starImg, &$shopNumImg){
                if ($resourcesModel->name == 'starImg' . $openShopSiteLocationModel->mallId) {
                    $starImg[] = picturePath($resourcesModel->url);
                }
                if ($resourcesModel->name == 'shopNumImg' . $openShopSiteLocationModel->mallId) {
                    $shopNumImg[] = picturePath($resourcesModel->url);
                }
            });

        if ($openShopSiteLocationModel->houseEvaluateStatus == SiteLocationEnum::HOUSE_EVALUATE_STATUS_FINISH) {
            $isMall = true;
            $isHave = true;
        }

        $result = [
            'info' => [
                'positionName' => '基本信息',
                'projects'  => [
                    PlaceHolderSiteLocationService::formUnit('mallId', 'text', '商场ID', $openShopSiteLocationModel->mallId, ['disabled' => true], []),
                    PlaceHolderSiteLocationService::formUnit('mallName', 'text', '大众点评商场名称', $openShopSiteLocationModel->mallName, ['disabled' => true], []),
                    PlaceHolderSiteLocationService::formUnit('mallStatus', 'select', '商城开业状态', (bool)$openShopSiteLocationModel->mallStatus,
                        [
                            'options' => [
                                [
                                    'text' => '已开业',
                                    'value' => true,
                                ],[
                                    'text' => '未开业',
                                    'value' => false,
                                ],
                            ],
                            'disabled' => true
                        ],
                        []),
                ]
            ],
            'mallGrade' => [
                'positionName' => '商场评分',
                'projects'  => [
                    PlaceHolderSiteLocationService::formUnit('star', 'number', '商场星级', $openShopSiteLocationModel->star, ['disabled' => $isHave], ['required' => true, 'max' => 5]),
                    PlaceHolderSiteLocationService::formUnit('facilitiesRating', 'number', '设施评分', $openShopSiteLocationModel->facilitiesRating, ['disabled' => $isHave], ['required' => true, 'max' => 10]),
                    PlaceHolderSiteLocationService::formUnit('environmentRating', 'number', '环境评分', $openShopSiteLocationModel->environmentRating, ['disabled' => $isHave], ['required' => true, 'max' => 10]),
                    PlaceHolderSiteLocationService::formUnit('serviceRating', 'number', '服务评分', $openShopSiteLocationModel->serviceRating, ['disabled' => $isHave], ['required' => true, 'max' => 10]),
                    PlaceHolderSiteLocationService::formUnit('starImg', 'imgGroup', '大众点评评分截图', $starImg, ['disabled' => $isHave], ['required' => false]),
                ]
            ],
            'shopInfo' => [
                'positionName' => '铺位信息',
                'projects'  => [
                    PlaceHolderSiteLocationService::formUnit('shopTotalNum', 'number', '铺位总数', $openShopSiteLocationModel->shopTotalNum, ['disabled' => $isHave], ['required' => true]),
                    PlaceHolderSiteLocationService::formUnit('gourmetShopNum', 'number', '美食类铺位', $openShopSiteLocationModel->gourmetShopNum, ['disabled' => $isHave], ['required' => true]),
                    PlaceHolderSiteLocationService::formUnit('goShoppingNum', 'number', '购物类铺位', $openShopSiteLocationModel->goShoppingNum, ['disabled' => $isHave], ['required' => true]),
                    PlaceHolderSiteLocationService::formUnit('shopNumImg', 'imgGroup', '大众点评铺位截图', $shopNumImg, ['disabled' => $isHave], ['required' => false])
                ]
            ],
            'business' => [
                'positionName' => '商圈信息',
                'projects'  => [
                    PlaceHolderSiteLocationService::formUnit('businessDistrict', 'text', '所在商圈', $openShopSiteLocationModel->businessDistrict, ['disabled' => $isMall], ['required' => !$isMall]),
                    PlaceHolderSiteLocationService::formUnit('businessMap', 'map', '商圈定位', (empty($openShopSiteLocationModel->businessMap) ? json_decode($openShopSiteLocationModel->businessMap ?? '[]', true) : null), ['disabled' => $isMall, 'display' => !$isMall], ['required' => !$isMall]),
                    PlaceHolderSiteLocationService::formUnit('businessArea', 'address', '省市区', $openShopSiteLocationModel->businessArea, ['disabled' => $isMall], ['required' => !$isMall]),
                    PlaceHolderSiteLocationService::formUnit('businessAddress', 'textarea', '详细地址', $openShopSiteLocationModel->businessAddress, ['disabled' => $isMall], ['required' => !$isMall]),
                ]
            ],

        ];

        return array_values($result);

    }
}
